package com.jumi.microservice.service.impl;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.jumi.microservice.common.constant.RequestConstant;
import com.jumi.microservice.common.exception.BusinessException;
import com.jumi.microservice.common.utils.ObjectUtils;
import com.jumi.microservice.constant.ExceptionEnum;
import com.jumi.microservice.constant.LabelEnum;
import com.jumi.microservice.constant.StatusEnum;
import com.jumi.microservice.domain.LabelDO;
import com.jumi.microservice.domain.LabelDTO;
import com.jumi.microservice.mapper.LabelMapper;
import com.jumi.microservice.service.LabelService;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
import java.util.List;

/**
 * 标签管理service组件接口
 *
 * @author Administrator
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class LabelServiceImpl implements LabelService {

    /**
     * 标签管理mapper组件
     */
    @Autowired
    private LabelMapper labelMapper;

    /**
     * 查询标签列表
     *
     * @param labelName 查询条件
     * @return 标签列表
     */
    @Override
    public List<LabelDTO> listLabel(String labelName) {
        LambdaQueryWrapper<LabelDO> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(LabelDO::getIsDel, StatusEnum.STATUS_NO.getCode());
        wrapper.like(StringUtils.isNotEmpty(labelName), LabelDO::getLabelName, labelName);
        wrapper.orderByDesc(LabelDO::getId);
        return convertLabelDoList2DtoList(labelMapper.selectList(wrapper));
    }

    /**
     * 添加商品页面-查询标签列表
     *
     * @return 标签列表
     */
    @Override
    public List<LabelDTO> dropListLabel() {
        LambdaQueryWrapper<LabelDO> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(LabelDO::getIsDel, StatusEnum.STATUS_NO.getCode());
        wrapper.eq(LabelDO::getStatus, StatusEnum.STATUS_YES.getCode());
        wrapper.orderByDesc(LabelDO::getId);
        return convertLabelDoList2DtoList(labelMapper.selectList(wrapper));
    }

    /**
     * 根据标签id查询标签
     *
     * @param id 标签id
     * @return 标签
     */
    @Override
    public LabelDTO getLabelById(Long id) {
        ExceptionEnum.FAIL_ID_NULL.doThrowIf(id == null);
        LabelDO label = labelMapper.selectById(id);
        ExceptionEnum.FAIL_NULL.doThrowIf(label == null);
        return convertLabelDo2Dto(label);
    }

    /**
     * 新增标签
     *
     * @param label   标签
     * @param request HttpServletRequest
     */
    @Override
    public void saveLabel(LabelDTO label, HttpServletRequest request) {
        ExceptionEnum.FAIL_NULL.doThrowIf(label == null);
        checkLabel(label);

        LabelDO labelDo = convertLabelDto2Do(label);
        ExceptionEnum.FAIL_UID_NULL.doThrowIf(request.getHeader(RequestConstant.ADMIN_NAME) == null);
        LocalDateTime localDateTime = LocalDateTime.now();
        labelDo.setCreateTime(localDateTime);
        labelDo.setUpdateTime(localDateTime);
        labelDo.setCreater(request.getHeader(RequestConstant.ADMIN_NAME));
        labelDo.setModifier(request.getHeader(RequestConstant.ADMIN_NAME));
        labelMapper.insert(labelDo);
    }

    /**
     * 更新标签
     *
     * @param label   标签
     * @param request HttpServletRequest
     */
    @Override
    public void updateLabel(LabelDTO label, HttpServletRequest request) {
        ExceptionEnum.FAIL_NULL.doThrowIf(label == null);
        checkLabel(label);

        LabelDO labelDo = convertLabelDto2Do(label);
        ExceptionEnum.FAIL_UID_NULL.doThrowIf(request.getHeader(RequestConstant.ADMIN_NAME) == null);
        LocalDateTime localDateTime = LocalDateTime.now();
        labelDo.setUpdateTime(localDateTime);
        labelDo.setModifier(request.getHeader(RequestConstant.ADMIN_NAME));
        labelMapper.updateById(labelDo);
    }

    /**
     * 检查是否存在未删除状态的同名的标签名称
     *
     * @param label 标签
     */
    private void checkLabel(LabelDTO label) {
        List<LabelDO> labelIdList = labelMapper.selectList(
                Wrappers.<LabelDO>lambdaQuery()
                        .select(LabelDO::getId)
                        .eq(LabelDO::getLabelName, label.getLabelName())
                        .eq(LabelDO::getIsDel, StatusEnum.STATUS_NO.getCode())
                        .ne(label.getId() != null, LabelDO::getId, label.getId()));

        if (labelIdList.size() > 0) {
            throw new BusinessException(LabelEnum.LABEL_HAS_EXISTED);
        }
    }

    /**
     * 删除标签
     *
     * @param id      标签id
     * @param request HttpServletRequest
     */
    @Override
    public void removeLabelById(Long id, HttpServletRequest request) {
        ExceptionEnum.FAIL_ID_NULL.doThrowIf(id == null);

        LabelDO label = labelMapper.selectById(id);
        if (label.getStatus().equals(StatusEnum.STATUS_YES.getCode())) {
            throw new BusinessException(LabelEnum.LABEL_STATUS_ABLED);
        }
        ExceptionEnum.FAIL_UID_NULL.doThrowIf(request.getHeader(RequestConstant.ADMIN_NAME) == null);
        label.setIsDel(StatusEnum.STATUS_YES.getCode());
        label.setModifier(request.getHeader(RequestConstant.ADMIN_NAME));
        label.setUpdateTime(LocalDateTime.now());
        labelMapper.updateById(label);
    }

    /**
     * 标签状态启用/停用
     *
     * @param id      主键id
     * @param status  状态 (1启用，0.禁用)
     * @param request HttpServletRequest
     */
    @Override
    public void enableStatus(Long id, Integer status, HttpServletRequest request) {
        LabelDO label = labelMapper.selectById(id);
        ExceptionEnum.FAIL_NULL.doThrowIf(label == null);

        ExceptionEnum.FAIL_UID_NULL.doThrowIf(request.getHeader(RequestConstant.ADMIN_NAME) == null);

        label.setStatus(status);
        label.setModifier(request.getHeader(RequestConstant.ADMIN_NAME));
        label.setUpdateTime(LocalDateTime.now());
        labelMapper.updateById(label);
    }


    /**
     * 将标签DTO对象转换为DO对象
     *
     * @param labelDTO 标签DTO
     * @return Label 标签DO
     */
    private LabelDO convertLabelDto2Do(LabelDTO labelDTO) {
        LabelDO label = null;
        try {
            label = labelDTO.clone(LabelDO.class);
        } catch (Exception e) {
            ExceptionEnum.FAIL_CHANGE.newException();
        }
        return label;
    }

    /**
     * 将标签DO对象转换为DTO对象
     *
     * @param label 标签DO
     * @return LabelDTO 标签DTO
     */
    private LabelDTO convertLabelDo2Dto(LabelDO label) {
        LabelDTO labelDto = null;
        try {
            labelDto = label.clone(LabelDTO.class);
        } catch (Exception e) {
            ExceptionEnum.FAIL_CHANGE.newException();
        }
        return labelDto;
    }

    /**
     * 将标签DO对象集合转换为DTO对象集合
     *
     * @param labels 标签DO集合
     * @return List<LabelDTO> 标签DTO对象集合
     */
    private List<LabelDTO> convertLabelDoList2DtoList(List<LabelDO> labels) {
        List<LabelDTO> labelDtoList = null;
        try {
            labelDtoList = ObjectUtils.convertList(labels, LabelDTO.class);
        } catch (Exception e) {
            ExceptionEnum.FAIL_CHANGE.newException();
        }
        return labelDtoList;
    }

}
